using Autofac;
using Autofac.Core;
using AvalonAdmin.Utils.UtilCache;
using D.Util.UtilNLog;
using D.UtilCore.JwtUtil;
using D.Util.UtilCache;
using System;
using System.Diagnostics;
using AvalonAdminCacheService = AvalonAdmin.Utils.UtilCache.CacheService;
using AvalonAdminICacheService = AvalonAdmin.Utils.UtilCache.ICacheService;
using DUtilCacheService = D.Util.UtilCache.CacheService;
using DUtilICacheService = D.Util.UtilCache.ICacheService;

namespace AvalonAdmin.Helpers
{
    /// <summary>
    /// 1、对于不使用接口的类可以直接使用RegisterType
    /// 2、对于多个继承接口的，不能直接使用RegisterType，要RegisterType方法后再添加Named方法，并指定一个字符串
    /// 3、对于一个实体类继承接口，并且继承的接口又有父接口的，可以指定不同的接口类型，使用时可以根据需求选择不同的接口，如按钮SecondModel和SecondModel2选择了不同的接口进行了使用
    /// </summary>
    public class AutoFacHelper
    {
        //在类中定义变量
        private static IContainer? _container { get; set; }

        private static readonly AutoFacHelper instance = new AutoFacHelper();
        public static AutoFacHelper Instance
        {
            get { return instance; }
        }

        public static void Initialize()
        {
            var builder = new ContainerBuilder();//实例化 Autofac 容器

            //builder.RegisterType<TestServiceImpl>(); //RegisterType ： 注册一个类
            builder.RegisterType<D.Util.UtilNLog.NLogService>().As<D.Util.UtilNLog.INLogService>().SingleInstance();  //单例模式
            
            // 注册AvalonAdmin命名空间的CacheService
            builder.RegisterType<AvalonAdminCacheService>().As<AvalonAdminICacheService>().SingleInstance();
            
            // 注册D.Util命名空间的CacheService
            builder.RegisterType<DUtilCacheService>().As<DUtilICacheService>().SingleInstance();
            
            builder.RegisterType<JwtService>().As<IJwtService>().SingleInstance();  //.InstancePerLifetimeScope(); //作用域模式

            _container = builder.Build();//使用已进行的组件登记创建新容器 

        }

        #region 获取对应接口的具体实现类 

        /// <summary>
        /// 获取实现类(默认映射)
        /// </summary>
        /// <typeparam name="T">接口类型</typeparam>
        /// <returns>接口</returns>
        public T Get<T>()
        {
            if (_container == null)
                throw new InvalidOperationException("Autofac container has not been initialized. Call Initialize() first.");

            if (!_container.IsRegistered<T>())
                throw new InvalidOperationException($"Service {typeof(T).Name} is not registered in Autofac.");

            return _container.Resolve<T>();
        }
        /// <summary>
        /// 获取实现类(默认映射)带参数的
        /// </summary>
        /// <typeparam name="T">接口类型</typeparam>
        /// <param name="parameter">参数</param>
        /// <returns>接口</returns>
        public T Get<T>(params Parameter[] parameter)
        {
            if (_container == null)
                throw new InvalidOperationException("Autofac container has not been initialized. Call Initialize() first.");

            if (!_container.IsRegistered<T>())
                throw new InvalidOperationException($"Service {typeof(T).Name} is not registered in Autofac.");

            return _container.Resolve<T>(parameter);
        }
        /// <summary>
        /// 获取实现类(指定映射)带参数的
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="name"></param>
        /// <param name="parameter"></param>
        /// <returns>接口</returns>
        public T Get<T>(string name, params Parameter[] parameter)
        {
            if (_container == null)
                throw new InvalidOperationException("Autofac container has not been initialized. Call Initialize() first.");

            if (!_container.IsRegistered<T>())
                throw new InvalidOperationException($"Service {typeof(T).Name} is not registered in Autofac.");

            return _container.Resolve<T>(parameter);
        }
        #endregion

        #region  判断接口是否被注册了 
        /// <summary>
        /// 判断接口是否被实现了
        /// </summary>
        /// <typeparam name="T">接口类型</typeparam>
        /// <returns>bool</returns>
        public bool IsResolve<T>()
        {
            return _container.IsRegistered<T>();
        }
        /// <summary>
        /// 判断接口是否被实现了
        /// </summary>
        /// <typeparam name="T">接口类型</typeparam>
        /// <param name="name">映射名称</param>
        /// <returns></returns>
        public bool IsResolve<T>(string name)
        {
            return _container.IsRegisteredWithName<T>(name);
        }
        #endregion
    }
}
